package com.secsbrain.development.biz.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.secsbrain.cmdb.client.iface.AppInfoService;
import com.secsbrain.common.ResponseResult;
import com.secsbrain.deploy.client.iface.DeployService;
import com.secsbrain.development.biz.constant.EnumDefinition;
import com.secsbrain.development.biz.exception.BizMessageException;
import com.secsbrain.development.remote.SsoRemoteService;
import com.secsbrain.sso.core.SsoHelper;
import com.secsbrain.sso.model.dto.system.UserDTO;
import com.secsbrain.sso.model.dto.system.UserDetailDTO;
import com.secsbrain.development.dal.mapper.DeployApprovalMapper;
import com.secsbrain.development.dal.model.DeployApproval;
import com.secsbrain.development.web.dto.ApproveDeployDTO;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.secsbrain.common.ResponseVo;
import com.secsbrain.engine.client.constant.ProcessKeyConstant;
import com.secsbrain.engine.client.iface.ProcessService;
import com.secsbrain.engine.client.model.ProcessDeal;
import com.secsbrain.engine.client.model.ProcessDto;
import com.secsbrain.engine.client.model.StartProcessParam;
import com.secsbrain.deploy.client.constant.EnumDefinition.BuildStatus;
import com.secsbrain.deploy.client.model.BuildParam;
import com.secsbrain.deploy.client.model.BuildRecord;
import com.secsbrain.development.biz.IDeployApprovalService;
import com.baomidou.framework.service.impl.SuperServiceImpl;

/**
 *
 * DeployApproval 表数据服务层接口实现类
 *
 */
@Service
public class DeployApprovalServiceImpl extends SuperServiceImpl<DeployApprovalMapper, DeployApproval> implements IDeployApprovalService {

    private static final Logger LOGGER = LoggerFactory.getLogger(DeployApprovalServiceImpl.class);

	@Autowired
	ProcessService processService;
	
	@Autowired
	DeployService deployService;
	
	@Autowired
	SsoRemoteService userServiceFacade;
	
	@Autowired
	AppInfoService appInfoService;

	/* (non-Javadoc)
	 * @see IDeployApprovalService#singleDeployApproval(DeployApproval)
	 */
	@Override
	public void singleDeployApproval(DeployApproval deployApproval) {
		UserDetailDTO userDTO= SsoHelper.currentUser();
		deployApproval.setCreateName(userDTO.getNickname());
		deployApproval.setCreateId(userDTO.getId());
		deployApproval.setCreateTime(new Date());
		deployApproval.setStatus(EnumDefinition.ApprovalStatus.INIT.getCode());//未审批
		
		this.approval(deployApproval,userDTO);
	}
	
	@Transactional
	private void approval(DeployApproval deployApproval,UserDetailDTO userDTO){
		LOGGER.debug("提交发布申请开始：{}", JSON.toJSONString(deployApproval));
		this.insertSelective(deployApproval);
		
		StartProcessParam startProcessParam=new StartProcessParam();
		
		ResponseVo<Long> qualityIdVo=appInfoService.queryQualityByAppId(deployApproval.getAppId());
		if(!qualityIdVo.isSuccess()||qualityIdVo.getData()==null||qualityIdVo.getData()==0){
			startProcessParam.setAssignee("1");//如果请求失败则是熊审批
		}else{
			Long qualityId=qualityIdVo.getData();
			startProcessParam.setAssignee(qualityId+"");
		}
		
		startProcessParam.setProcessDefinitionKey(ProcessKeyConstant.DEPLOY_KEY);
		startProcessParam.setStartUserId(userDTO.getId()+"");
		ResponseVo<ProcessDto> processVo=processService.startProcess(startProcessParam);
		if(!processVo.isSuccess()){
			LOGGER.error("启动流程失败："+processVo.getMsg());
			throw new RuntimeException(processVo.getMsg());
		}

		ResponseResult<UserDTO> userResult=userServiceFacade.getUserDTO(Long.parseLong(startProcessParam.getAssignee()));
		if(userResult.getCode()==1){
			List<String> emailList=new ArrayList<String>();
			if(userResult.getData()!=null&&userResult.getData().getEmail()!=null){
				emailList.add(userResult.getData().getEmail());
			}
			sendStartNotice(emailList, "您有发布需要审批，请登录http://devops.secsbrain.com");
		}else{
			LOGGER.error("调用获取用户信息接口失败："+userResult.getMsg());
		}
		
		DeployApproval deployApprovalUp=new DeployApproval();
		deployApprovalUp.setId(deployApproval.getId());
		deployApprovalUp.setProcessInstanceId(processVo.getData().getProcessInstanceId());
		this.updateSelectiveById(deployApprovalUp);
	}
	
	/* (non-Javadoc)
	 * @see IDeployApprovalService#groupBApproval(java.lang.Long, java.lang.String)
	 */
	@Override
	public void groupBApproval(Long groupId, String envName) {
		//TODO 如果发现已经在审批中，就不允许申请了
		
		ResponseVo<List<BuildRecord>> subBuildRecordVo=deployService.queryBuildListByGroupId(groupId, envName);
        List<BuildRecord> buildRecordList=subBuildRecordVo.getData();
		if (!subBuildRecordVo.isSuccess()||CollectionUtils.isEmpty(buildRecordList)) {
            throw new BizMessageException("无效的发布记录ID");
        }
		
		boolean flag=true;
        for(BuildRecord buildRecord:buildRecordList){
        	if(!BuildStatus.SUCCESS.getCode().equals(buildRecord.getStatus())){
        		flag=false;
        		break;
        	}
        }
        
        //A组失败了则不让继续
        if(!flag){
        	throw new BizMessageException("灰度执行没有成功");
        }
        
        DeployApproval deployApproval=new DeployApproval();
		BuildRecord buildRecord=buildRecordList.get(0);
		deployApproval.setAppId(buildRecord.getAppId());
		deployApproval.setBranch(buildRecord.getBranch());
		deployApproval.setEnv(envName);
		deployApproval.setGroupId(groupId);
		deployApproval.setGroupName("B");
		
		UserDetailDTO userDTO=SsoHelper.currentUser();
		deployApproval.setCreateName(userDTO.getNickname());
		deployApproval.setCreateId(userDTO.getId());
		deployApproval.setCreateTime(new Date());
		deployApproval.setStatus(EnumDefinition.ApprovalStatus.INIT.getCode());//未审批
		
		this.approval(deployApproval,userDTO);
	}
	
	@SuppressWarnings("rawtypes")
	@Async
	public void sendStartNotice(List<String> emailList,String msg) {
		if(CollectionUtils.isEmpty(emailList)){
			return;
		}
		
//		try {
//			LOGGER.debug("发送钉钉消息。。。msg:{}，emailList:{}",msg,JSON.toJSONString(emailList));
//
//			Map result=kapiClient.sendDingMsg(emailList, "遁地研发平台通知：", msg);
//			if(!(Boolean)result.get("success")){
//				LOGGER.error((String)result.get("message"));
//			}
//		} catch (Exception e) {
//			LOGGER.error("发送钉钉消息异常",e);
//		}
		
		try {
			LOGGER.debug("发送邮件。。。msg:{}，emailList:{}",msg,JSON.toJSONString(emailList));

//			for(String email:emailList){
//				MailDto mailDto=new MailDto();
//				mailDto.setEmail(email);
//				mailDto.setName(email);
//				mailDto.setMailType(MailDto.MAILTYPE_NOTICE);
//				mailDto.setCheckUrl(msg);
//				mailDto.setUsername(msg);
//				mailSendService.sendMail(mailDto);
//			}
		} catch (Exception e) {
			LOGGER.error("发送邮件异常",e);
		}
    }

	/* (non-Javadoc)
	 * @see IDeployApprovalService#approve(ApproveDeployDTO)
	 */
	@Override
	@Transactional
	public void approve(ApproveDeployDTO approveProjectDTO) {
		DeployApproval deployApproval=this.selectById(approveProjectDTO.getId());
		deployApproval.setAppName(appInfoService.queryAppDetailById(deployApproval.getAppId()).getData().getName());
		
		LOGGER.debug("审批发布开始：{}",JSON.toJSONString(deployApproval));
		
		UserDetailDTO userDetailDTO=SsoHelper.currentUser();

		DeployApproval deployApprovalUp=new DeployApproval();
		deployApprovalUp.setId(approveProjectDTO.getId());
		if(approveProjectDTO.getPass()){
			deployApprovalUp.setStatus(EnumDefinition.ApprovalStatus.AGREE.getCode());
		}else{
			deployApprovalUp.setStatus(EnumDefinition.ApprovalStatus.REFUSE.getCode());
			deployApprovalUp.setComment(userDetailDTO.getRealName()+"驳回："+approveProjectDTO.getComment());
		}
		this.updateSelectiveById(deployApprovalUp);
		
		ProcessDeal processDeal=new ProcessDeal();
		processDeal.setProcessInstanceId(deployApproval.getProcessInstanceId());
		processDeal.setUserId(userDetailDTO.getId()+"");
		if(CollectionUtils.isNotEmpty(userDetailDTO.getUserRoleList())){
			processDeal.setRoleCode(userDetailDTO.getUserRoleList().get(0).getCode());
		}else{
			processDeal.setRoleCode("dev_develop");
		}

		ResponseResult<UserDTO> userResult=userServiceFacade.getUserDTO(deployApproval.getCreateId());
		List<String> emailList=new ArrayList<String>();
		if(userResult.getCode()==1){
			if(userResult.getData()!=null&&userResult.getData().getEmail()!=null){
				emailList.add(userResult.getData().getEmail());
			}
		}else{
			LOGGER.error("调用获取用户信息接口失败："+userResult.getMsg());
		}
		
		ResponseVo<String> processVo=null;
		if(approveProjectDTO.getPass()){
			//通过流程
			processVo=processService.pass(processDeal);
		}else{
			processVo=processService.refuse(processDeal);
		}
		
		if(!processVo.isSuccess()){
			LOGGER.error("审批失败："+processVo.getMsg());
			throw new RuntimeException(processVo.getMsg());
		}
		
		if(approveProjectDTO.getPass()){
			BuildParam buildParam=new BuildParam();
			buildParam.setAppId(deployApproval.getAppId());
			buildParam.setBranchName(deployApproval.getBranch());
			buildParam.setBuildUserName(deployApproval.getCreateName());
			buildParam.setEnvName(deployApproval.getEnv());
			// 分组ID为0是默认为空
			if(deployApproval.getGroupId()!=null&&deployApproval.getGroupId()==0){
				buildParam.setGroupId(null);
			}else{
				buildParam.setGroupId(deployApproval.getGroupId());
			}
			buildParam.setGroupName(deployApproval.getGroupName());
			if("B".equals(deployApproval.getGroupName())){
				buildParam.setPackage(false);
			}
			buildParam.setApprovalId(deployApproval.getId());
			buildParam.setK8s(true);//TODO 目前审批都是prod环境，且prod环境都是k8s部署，所以暂且写死，有需要再作调整
			ResponseVo<Long> buildPreVo=deployService.buildPre(buildParam);
			//TODO 此处涉及到分布式事务
			if(!buildPreVo.isSuccess()){
				LOGGER.error("构建准备失败，请系统管理员注意异常处理！消息："+buildPreVo.getMsg());
			}else{
				sendStartNotice(emailList, "您的发布申请【应用"+deployApproval.getAppName()+"】已审批通过，请登录系统继续操作");
			}
		}else{
			sendStartNotice(emailList, "您的发布申请【应用"+deployApproval.getAppName()+"】被"+userDetailDTO.getRealName()+"驳回，原因是\""+approveProjectDTO.getComment()+"\"");
		}
		
	}

}